package com.easyskool.utilfunction;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.core.Response;

import org.json.JSONException;
import org.json.JSONObject;

import com.easyskool.constants.CommonConstants;
import com.easyskool.constants.MessageConstants;
import com.easyskool.dao.BaseDao;
import com.easyskool.exception.DaoException;
import com.easyskool.hibernate.model.AccessGroupMapper;
import com.easyskool.hibernate.model.AccessGroups;
import com.easyskool.hibernate.model.AccessRights;
import com.easyskool.hibernate.model.ResourceDetails;
import com.easyskool.hibernate.model.Schools;
import com.easyskool.util.HibernateUtil;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

public class UtilFunctions {

	public static HashMap<String, Integer> getAllowedsubGroups(
			HashMap<String, Integer> subGroups, String accessGroup,
			Schools school) throws Exception {
		HashMap<String,Integer> hm=HibernateUtil.basicGroups;
		if (accessGroup.equals(CommonConstants.ADMIN_GROUP))
		{
			Iterator it = hm.entrySet().iterator();
		    while (it.hasNext()) {
		        Map.Entry pairs = (Map.Entry)it.next();
		        System.out.println(pairs.getKey() + " = " + pairs.getValue());
		        String allowedGroup=(String) pairs.getKey();
		        if(subGroups.containsKey(allowedGroup))
		        {
		        	int count=subGroups.get(allowedGroup);
		        	subGroups.put(allowedGroup,count+1);
		        }
//		        it.remove(); // avoids a ConcurrentModificationException
		    }

			
			return subGroups;
		}
		HashMap<String, Object> whereMap = new HashMap<String, Object>();
		AccessGroups ag = new AccessGroups();
		ag.setAgCode(accessGroup);
		System.out.println("AccessGroups: " + accessGroup + ", School: "
				+ school.getSchoolName());
		whereMap.put("accessGroupsByAgmCustomGroupCode", ag);
		whereMap.put("schools", school);
		String sql = "from AccessGroupMapper where accessGroupsByAgmCustomGroupCode=:accessGroupsByAgmCustomGroupCode  and schools=:schools";
		List<AccessGroupMapper> aginCustomGroup = HibernateUtil.baseDaoStatic
				.customQuery(sql, whereMap);
		System.out.println("Size off adginCg: " + aginCustomGroup.size());
		for(int i=0;i<aginCustomGroup.size();i++)
		{
			String allowedGroup=aginCustomGroup.get(i).getAccessGroupsByAgmDefaultGroupCode().getAgCode();
			if(subGroups.containsKey(allowedGroup))
	        {
	        	int count=subGroups.get(allowedGroup);
	        	subGroups.put(allowedGroup,count+1);
	        }
			
		}
		return subGroups;

	}

	public static String generateString(int length) {
		Random rng = new Random();
		String characters = "abcdefghijklmnopqrstuvwxyz1234567890";
		char[] text = new char[length];
		for (int i = 0; i < length; i++) {
			text[i] = characters.charAt(rng.nextInt(characters.length()));
		}
		System.out.println("Random String generate is " + new String(text));
		return new String(text);
	}

	public static boolean verifyPath(
			HashMap<String, ArrayList<String>> accessRights, String path,
			String accessGroup) {
		if (accessRights == null || path.equals("") || path == null
				|| accessGroup == null) {
			return false;
		}
		ArrayList<String> pathsAllowed = accessRights.get(accessGroup);
		for (int i = 0; i < pathsAllowed.size(); i++) {
			if (pathsAllowed.get(i).equals(path)) {
				return true;
			}
		}

		return false;
	}

	public static void initializeDefaultGroupVar() {
		System.out.println("Default Group variable initializing started");
		HibernateUtil.groups.clear();
		HibernateUtil.basicGroups.clear();
		Map<String, Object> whereMap = new HashMap<String, Object>();
		try {
			List<AccessRights> accessRights = HibernateUtil.baseDaoStatic.find(
					AccessRights.class, whereMap);
			for (int i = 0; i < accessRights.size(); i++) {
				String key = accessRights.get(i).getResourceDetails()
						.getRdPath();
				String group = accessRights.get(i).getAccessGroups()
						.getAgCode();
				if (HibernateUtil.groups.containsKey(key)) {
					HibernateUtil.groups.get(key).add(group);
				} else {
					ArrayList<String> gps = new ArrayList<String>();
					gps.add(group);
					HibernateUtil.groups.put(key, gps);
				}
				// Code for admin static variable
				if (HibernateUtil.basicGroups.containsKey(group)) {
					int count = HibernateUtil.basicGroups.get(group);
					count++;
					HibernateUtil.basicGroups.put(group, count);
				} else {
					HibernateUtil.basicGroups.put(group, 1);
				}
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("Default Group variable initializing ended");
	}

	public static boolean verifyPathfromDB(String path, String accessGroup) {
		Map<String, Object> whereMap = new HashMap<String, Object>();
		List<ResourceDetails> rds = new ArrayList<ResourceDetails>();
		try {
			System.out.println("Path in util is: " + path);
			whereMap.put("rdPath", path);
			rds = HibernateUtil.baseDaoStatic.find(ResourceDetails.class,
					whereMap);
			whereMap.clear();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		AccessGroups ag = new AccessGroups();
		ag.setAgCode(accessGroup);
		// Code to add new resource to the database-- Start
		ResourceDetails rd = new ResourceDetails();
		System.out.println("Number of resources got: " + rds.size());
		if (rds.size() == 0) {
			System.out.println("Adding the new rest to the db");
			addResttoDB(path, HibernateUtil.baseDaoStatic);
			System.out.println("Size is zero ");
			return false;
		}
		// Code to add new resource to the database-- End
		// Code to initialize the default group variable -- Start
		if (HibernateUtil.groups.size() == 0) {
			initializeDefaultGroupVar();
		}
		// Code to initialize the default group variable -- End
		// Code to check for access of admin user-Start
		if (CommonConstants.ADMIN_GROUP.equals(accessGroup)) {
			System.out.println("In the admin group checkpoint");
			ArrayList<String> GroupsForPathAPI = HibernateUtil.groups.get(path);
			if (GroupsForPathAPI == null)
				return false;
			for (int i = 0; i < GroupsForPathAPI.size(); i++) {
				String group = GroupsForPathAPI.get(i);
				if (HibernateUtil.basicGroups.containsKey(group))
					return true;
				else
					return false;

			}
		}
		// Code to check for access of admin user-End

		// Code to get the available default groups for a particular group --
		// Start
		whereMap.clear();
		List<AccessGroupMapper> defaultGroups = new ArrayList<AccessGroupMapper>();
		whereMap.put("accessGroupsByAgmCustomGroupCode", ag);
		try {
			defaultGroups = HibernateUtil.baseDaoStatic.find(
					AccessGroupMapper.class, whereMap);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		whereMap.clear();
		// Code to get the available default groups for a particular group --
		// End
		// Code to find the common element in both the arrays -- End
		ArrayList<String> groupWithPath = HibernateUtil.groups.get(path); // groups
																			// in
																			// which
																			// the
																			// pathis
																			// present
		for (int i = 0; i < groupWithPath.size(); i++) {

			for (int j = 0; j < defaultGroups.size(); j++) {
				String customDefaultGroup = defaultGroups.get(j)
						.getAccessGroupsByAgmDefaultGroupCode().getAgCode();
				String websiteDefaultGroup = groupWithPath.get(i);
				System.out.println("i: " + i + " J: " + j);
				System.out.println("map: " + customDefaultGroup + " hib: "
						+ websiteDefaultGroup);

				if (customDefaultGroup.equals(websiteDefaultGroup)) {
					System.out.println("Found the element");
					return true;
				}
			}
		}
		// Code to find the common element in both the arrays -- End
		return false;
	}

	private static void addResttoDB(String path, BaseDao base) {

		ResourceDetails rd = new ResourceDetails();
		rd.setCreatedBy("system");
		rd.setModifiedBy("system");
		rd.setCreatedDate(new Date());
		rd.setModifiedDate(new Date());
		rd.setRdPath(path);
		rd.setStatus(1);
		String splitPaths[] = path.split("/");
		System.out.println("Second half is "
				+ splitPaths[splitPaths.length - 1]);
		rd.setRdCode(splitPaths[splitPaths.length - 1]);
		rd.setRdName(splitPaths[splitPaths.length - 1]);
		rd.setRdDescription(splitPaths[splitPaths.length - 1]);
		try {
			HibernateUtil.baseDaoStatic.insertWithObject(ResourceDetails.class,
					rd);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static Response createSuccessResponse(int statusCode,
			String successCode, String successMessage) throws JSONException {

		JSONObject jsonObject = new JSONObject();

		jsonObject.put(MessageConstants.RESPONSE_CODE, successCode);
		jsonObject.put(MessageConstants.RESPONSE_MESSAGE, successMessage);

		String result = String.valueOf(jsonObject);

		return Response.status(statusCode).entity(result).build();
	}

	public static Response createSuccessCustomResponse(int statusCode,
			String successCode, Object successMessage) throws JSONException {

		JSONObject jsonObject = new JSONObject();

		jsonObject.put(MessageConstants.RESPONSE_CODE, successCode);
		jsonObject.put(MessageConstants.RESPONSE_MESSAGE, successMessage);

		String result = String.valueOf(jsonObject);

		return Response.status(statusCode).entity(result).build();
	}

	/**
	 * Used for sending mapped string
	 * 
	 * @param statusCode
	 * @param str
	 * @return
	 * @throws JSONException
	 */
	public static Response createObjectResponse(int statusCode, Object str)
			throws JSONException {

		return Response.status(statusCode).entity(str).build();
	}

	public static Response createErrorResponse(int statusCode,

	String errorCode, String errorMessage) throws JSONException {
		JSONObject jsonObject = new JSONObject();

		jsonObject.put(MessageConstants.ERROR_CODE, errorCode);
		jsonObject.put(MessageConstants.ERROR_MESSAGE, errorMessage);

		String result = String.valueOf(jsonObject);

		return Response.status(statusCode).entity(result).build();
	}

	// --------------------------------------------------------------------------
	public static String createErrorJson(String errorCode, String errorMessage)
			throws JSONException {
		JSONObject jsonObject = new JSONObject();

		jsonObject.put(MessageConstants.ERROR_CODE, errorCode);
		jsonObject.put(MessageConstants.ERROR_MESSAGE, errorMessage);

		String result = String.valueOf(jsonObject);

		return result;
	}

	// --------------------------------------------------------------------------------------------
	public static String createJsonObject(String CRUDType, String status)
			throws JSONException {

		JSONObject jsonObject = new JSONObject();
		jsonObject.put(CRUDType, status);
		return jsonObject.toString();
	}

	public static JsonObject convertMapToJson(Map<String, Object> inputMap) {

		Set<String> keys = new HashSet<>();
		keys = inputMap.keySet();
		JsonObject jobject = new JsonObject();
		for (String key : keys) {
			String value = String.valueOf(inputMap.get(key));
			jobject.addProperty(key, value);
		}
		return jobject;
	}

	public static String createResultSet(List<Map> inputList) throws Exception {
		JsonArray json_arr = new JsonArray();
		if (!NullObjects.isNull(inputList)) {
			for (Map inputMap : inputList) {
				JsonObject json_obj = convertMapToJson(inputMap);
				json_arr.add(json_obj);
			}
		}
		return json_arr.toString();
	}

	public static String insertParamAdd(String user, String toInsert) {
		String today = UtilFunctions.getDateString();
		String addInsertString = ",\"createdBy\":\"" + user
				+ "\",\"createdDate\":\"" + today + "\",\"modifiedBy\":\""
				+ user + "\",\"modifiedDate\":\"" + today + "\"}";
		toInsert = toInsert.replace("}", addInsertString);

		return toInsert;
	}

	public static String updateParamAdd(String user, String updateClause) {
		String today = UtilFunctions.getDateString();
		String addUpdateString = ",\"modifiedBy\":\"" + user
				+ "\",\"modifiedDate\":\"" + today + "\"}";
		updateClause = updateClause.replace("}", addUpdateString);

		return updateClause;
	}

	public static String getDateString() {
		Date todaydate = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat(
				"yyyy-MM-dd'T'HH:mm:ss.SSSZ");
		String today = dateFormat.format(todaydate);

		return today;
	}
	
	public static  java.lang.String getUserName(HttpServletRequest req)
	{
		HttpSession session= req.getSession(true);
		String user="";
		user=(String) session.getAttribute(CommonConstants.USERCODE);
		return user;
	}

	public static String insertParamRequestAdd(String user, String toInsert) {
		Date todaydate = new Date();
		String today = UtilFunctions.getDateString();
		SimpleDateFormat codeDateFormat = new SimpleDateFormat(
				"yyyy-MM-dd-HH-mm-ss");
		String codeFormattedString = codeDateFormat.format(todaydate);

		String addInsertString = ",\"requestStatusChangedBy\":\"" + "null"
				+ "\",\"createdDate\":\"" + today
				+ "\",\"requestStatusChangedDate\":\"" + ""
				+ "\" ,\"schoolCode\":\"" + user + codeFormattedString + "\"}";
		toInsert = toInsert.replace("}", addInsertString);

		return toInsert;
	}

}
